// Package registry
// Title 			nacos.registry.components.go
// Description 		Nacos 注册中心工厂, 实现 factory.ApplicationRegistryLoaderFactory, 实现其远程加载器接口方法
// Author  			alittlexincan@163.com 					2024/07/22 11:36
// Update  			alittlexincan@163.com 					2024/07/22 11:36
package registry

import (
	"path/filepath"
	"strings"

	"github.com/nacos-group/nacos-sdk-go/v2/clients"
	"github.com/nacos-group/nacos-sdk-go/v2/common/constant"
	"github.com/nacos-group/nacos-sdk-go/v2/vo"
	"go.uber.org/zap"
	"xincan.com.cn/tarot-go/internal/common/constants"
	"xincan.com.cn/tarot-go/internal/config/factory"
)

// nacosRegistryComponent
// Title 			nacosRegistryComponent
// Description 		NACOS 注册中心结构体
// Author  			alittlexincan@163.com 					2024/07/22 11:36
// Update  			alittlexincan@163.com 					2024/07/22 11:36
type nacosRegistryComponent struct {
	factory.BaseConfigLoader[factory.ApplicationRegistryLoaderFactory]        // 基础配置加载器, 内置全局配置和日志
	*service                                                                  // 服务信息
	IP                                                                 string `mapstructure:"ip" json:"ip"`                   // 服务器IP
	Port                                                               int    `mapstructure:"port" json:"port"`               // 服务器端口
	Username                                                           string `mapstructure:"username" json:"username"`       // 用户名
	Password                                                           string `mapstructure:"password" json:"password"`       // 密码
	NamespaceId                                                        string `mapstructure:"namespaceId" json:"namespaceId"` // 命名空间ID
	Group                                                              string `mapstructure:"group" json:"group"`             // 分组
	CacheDir                                                           string `mapstructure:"cacheDir" json:"cacheDir"`       // 缓存目录
	LogDir                                                             string `mapstructure:"logDir" json:"logDir"`           // 日志目录

}

// ConfigLoad
// Title 			ConfigLoad
// Description 		实现 factory.ApplicationRegistryLoaderFactory 接口方法, 获取Nacos注册中心配置信息
// Author  			alittlexincan@163.com 							2024/07/22 11:36
// Update  			alittlexincan@163.com 							2024/07/22 11:36
// Return    		factory.ApplicationRegistryLoaderFactory 		返回注册中心工厂实例
func (nacos *nacosRegistryComponent) ConfigLoad() (interface{}, factory.ApplicationRegistryLoaderFactory) {
	nacos.service = &service{
		address: nacos.App.Config.Ip,
		port:    nacos.App.Config.Port,
		name:    nacos.App.Config.Name,
		logPath: nacos.App.Config.Log.Path,
	}
	namingClient, _ := clients.NewNamingClient(
		vo.NacosClientParam{
			ClientConfig:  nacos.setNacosRegistryClient(),
			ServerConfigs: nacos.setNacosRegistryServer(),
		},
	)
	if _, err := namingClient.RegisterInstance(vo.RegisterInstanceParam{
		Ip:          nacos.service.address,
		Port:        uint64(nacos.service.port),
		ServiceName: nacos.service.name,
		Weight:      10,
		Enable:      true,
		Healthy:     true,
		Ephemeral:   true,
		Metadata:    map[string]string{"idc": "shanghai"},
		GroupName:   nacos.Group,
	}); err != nil {
		nacos.Logger.Error("当前服务注册失败", zap.Error(err))
		return nil, nil
	}
	nacos.Logger.Info("当前服务注册成功")
	return namingClient, nacos
}

// setNacosRegistryClient
// Title 			setNacosRegistryClient
// Description 		内置辅助函数: 设置Nacos客户端配置
// Author      		alittlexincan@163.com       			2024/07/22 11:36
// Update  			alittlexincan@163.com 					2024/07/22 11:36
// Return    		*constant.ClientConfig				    返回Nacos客户端配置
func (nacos *nacosRegistryComponent) setNacosRegistryClient() *constant.ClientConfig {
	logDir, cacheDir, namespace := "", "", ""
	if nacos.LogDir == "" {
		if nacos.logPath == "" {
			logDir = constants.DefaultLogsDir + "/nacos/log"
		} else {
			logDir = filepath.Clean(nacos.logPath + "/nacos/log")
		}
	} else {
		logDir = filepath.Clean(nacos.LogDir + "/nacos/log")
	}

	if nacos.CacheDir == "" {
		cacheDir = filepath.Clean(constants.DefaultLogsDir + "/nacos/cache")
	} else {
		cacheDir = filepath.Clean(nacos.CacheDir + "/nacos/cache")
	}

	if nacos.NamespaceId != "public" {
		namespace = nacos.NamespaceId
	}
	return constant.NewClientConfig(
		constant.WithTimeoutMs(10000),            // 请求Nacos服务器超时时间，默认10000ms
		constant.WithNamespaceId(namespace),      // 命名空间ID，public命名空间留空
		constant.WithAppName(nacos.service.name), // 应用名称
		constant.WithCacheDir(cacheDir),          // 缓存目录
		constant.WithLogDir(logDir),              // 日志目录
		constant.WithLogLevel("info"),            // 日志级别: debug, info, warn, error
		constant.WithNotLoadCacheAtStart(true),   // 启动时不读取本地缓存
		constant.WithUpdateCacheWhenEmpty(true),  // 从服务器获取空服务实例时更新缓存
		constant.WithUsername(nacos.Username),    // Nacos认证用户名
		constant.WithPassword(nacos.Password),    // Nacos认证密码
	)
}

// setNacosRegistryServer
// Title 			setNacosRegistryServer
// Description 		辅助函数: 设置Nacos服务器配置
// Author      		alittlexincan@163.com       			2024/07/22 11:36
// Update  			alittlexincan@163.com 					2024/07/22 11:36
// Return    		[]constant.ServerConfig					返回Nacos服务器配置
func (nacos *nacosRegistryComponent) setNacosRegistryServer() []constant.ServerConfig {
	ipAddr := "127.0.0.1"
	if nacos.IP != "" {
		ipAddr = strings.Split(nacos.IP, "//")[1]
	}
	// 1. 创建Nacos服务器配置
	serverConfigs := []constant.ServerConfig{
		*constant.NewServerConfig(
			ipAddr,
			uint64(nacos.Port),
			constant.WithScheme(constant.DEFAULT_SERVER_SCHEME),
			constant.WithContextPath(constant.DEFAULT_CONTEXT_PATH),
		),
	}
	return serverConfigs
}

// init
// Title 			init
// Description 		初始化时自动实例化自身实例, 并在main包中导入当前包路径
// Author      		alittlexincan@163.com       			2024/07/17 11:36
// Update    		alittlexincan@163.com       			2024/07/17 11:36
func init() {
	factory.RegisterCenterFactory(constants.ProviderRegistryNacos, &nacosRegistryComponent{})
}
